Merge pull request 'Raise @novox/mesh-sdk to 0.1.17, and a unit test refuses a packed change that keeps its version (issue 1899, met twice)' (#75) from fix/1899-version-guard into main
Reviewed-on: #75
This commit was merged in pull request #75.
This commit is contained in:
@@ -0,0 +1,104 @@
|
|||||||
|
package packageguard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The registry refuses a second, different package under one version
|
||||||
|
// ("version taken", issues 1899 and 1331). This guard fails before a merge when
|
||||||
|
// what npm packs changes while the version stays: package-version.sum holds the
|
||||||
|
// version and a sha256 over the inputs of the packed dist (package.json without
|
||||||
|
// its version, src/, tsconfig.json) and of the README npm always packs.
|
||||||
|
// The lock file is not packed, so it is not hashed.
|
||||||
|
|
||||||
|
const sumFile = "package-version.sum"
|
||||||
|
|
||||||
|
func packedInputs(root string) (version, sum string, err error) {
|
||||||
|
raw, err := os.ReadFile(filepath.Join(root, "package.json"))
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
var pkg map[string]any
|
||||||
|
if err := json.Unmarshal(raw, &pkg); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
version, _ = pkg["version"].(string)
|
||||||
|
delete(pkg, "version")
|
||||||
|
canon, err := json.Marshal(pkg) // map keys are sorted: stable bytes
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
files := map[string][]byte{"package.json": canon}
|
||||||
|
for _, name := range []string{"tsconfig.json", "README.md"} {
|
||||||
|
b, err := os.ReadFile(filepath.Join(root, name))
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
files[name] = b
|
||||||
|
}
|
||||||
|
err = filepath.WalkDir(filepath.Join(root, "src"), func(p string, d fs.DirEntry, err error) error {
|
||||||
|
if err != nil || d.IsDir() {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b, err := os.ReadFile(p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rel, _ := filepath.Rel(root, p)
|
||||||
|
files[filepath.ToSlash(rel)] = b
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
names := make([]string, 0, len(files))
|
||||||
|
for n := range files {
|
||||||
|
names = append(names, n)
|
||||||
|
}
|
||||||
|
sort.Strings(names)
|
||||||
|
h := sha256.New()
|
||||||
|
for _, n := range names {
|
||||||
|
fmt.Fprintf(h, "%s\x00%d\x00", n, len(files[n]))
|
||||||
|
h.Write(files[n])
|
||||||
|
}
|
||||||
|
return version, hex.EncodeToString(h.Sum(nil)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPackageVersionMatchesPackedInputs(t *testing.T) {
|
||||||
|
root := "../.."
|
||||||
|
if r := os.Getenv("MESH_SDK_ROOT"); r != "" {
|
||||||
|
root = r
|
||||||
|
}
|
||||||
|
version, sum, err := packedInputs(root)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
line := version + " " + sum + "\n"
|
||||||
|
if os.Getenv("UPDATE_PACKAGE_VERSION_SUM") != "" {
|
||||||
|
if err := os.WriteFile(filepath.Join(root, sumFile), []byte(line), 0o644); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
raw, err := os.ReadFile(filepath.Join(root, sumFile))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s is missing: %v", sumFile, err)
|
||||||
|
}
|
||||||
|
recVersion, recSum, _ := strings.Cut(strings.TrimSpace(string(raw)), " ")
|
||||||
|
switch {
|
||||||
|
case recVersion == version && recSum == sum:
|
||||||
|
case recVersion == version:
|
||||||
|
t.Fatalf("what npm packs for @novox/mesh-sdk changed while its version stayed %s: the registry would refuse a second, different %s. Raise @novox/mesh-sdk's version (package.json and package-lock.json) and update %s (UPDATE_PACKAGE_VERSION_SUM=1 go test -run TestPackageVersionMatchesPackedInputs in go/packageguard)", version, version, sumFile)
|
||||||
|
default:
|
||||||
|
t.Fatalf("package.json says %s but %s records %s: update %s (UPDATE_PACKAGE_VERSION_SUM=1 go test -run TestPackageVersionMatchesPackedInputs in go/packageguard)", version, sumFile, recVersion, sumFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@novox/mesh-sdk",
|
"name": "@novox/mesh-sdk",
|
||||||
"version": "0.1.16",
|
"version": "0.1.17",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@novox/mesh-sdk",
|
"name": "@novox/mesh-sdk",
|
||||||
"version": "0.1.16",
|
"version": "0.1.17",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.0.0",
|
"@types/node": "^22.0.0",
|
||||||
"typescript": "^5.6.0"
|
"typescript": "^5.6.0"
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
0.1.17 90cca0bf1acfb386d66ccddb9f612703cf8f0205791b846982a524d0044aa0fb
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@novox/mesh-sdk",
|
"name": "@novox/mesh-sdk",
|
||||||
"version": "0.1.16",
|
"version": "0.1.17",
|
||||||
"description": "The stable spine a Novox Mesh module's own code builds against.",
|
"description": "The stable spine a Novox Mesh module's own code builds against.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
Reference in New Issue
Block a user