modules/npm: Make the generated workspace package private with a stable name

The autogenerated packages/hugoautogen/package.json got its name from the
project directory basename and had no "private" field, making it publishable
under checkout-dependent names. Use the stable default name "hugoautogen",
set "private": true, and preserve hand-set name/version/private on
regeneration.

Fixes #15245

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bjørn Erik Pedersen
2026-08-27 14:53:33 +02:00
parent 166d3ee1ce
commit df4ac34856
5 changed files with 66 additions and 12 deletions
+18 -5
View File
@@ -195,15 +195,28 @@ func Pack(sourceFs, assetsWithDuplicatesPreservedFs afero.Fs, mods modules.Modul
}
}
name := "project"
rfi, err := sourceFs.Stat("")
if err == nil {
name = rfi.Name()
// Stable defaults; mark the workspace private so npm never publishes it.
// Preserve any hand-set values from an existing file.
name, version, private := "hugoautogen", "0.1.0", true
if data, err := afero.ReadFile(sourceFs, workspacePackageJSON); err == nil {
var existing map[string]any
if err := json.Unmarshal(data, &existing); err == nil {
if s, ok := existing["name"].(string); ok && s != "" {
name = s
}
if s, ok := existing["version"].(string); ok && s != "" {
version = s
}
if b, ok := existing["private"].(bool); ok {
private = b
}
}
}
autoGenPkg := map[string]any{
"name": name,
"version": "0.1.0",
"version": version,
"private": private,
dependenciesKey: moduleDeps,
devDependenciesKey: moduleDevDeps,
}
@@ -92,6 +92,40 @@ func TestPackageBuilder(t *testing.T) {
b.Assert(string(meta2), qt.Equals, string(meta1))
}
// The generated workspace package.json should get a stable name and
// "private": true, and preserve hand-set name/version/private on regeneration.
// See issue 15245.
func TestPackStableNameAndPrivate(t *testing.T) {
files := getPackageBuilderTestFiles()
b := hugolib.Test(t, files)
sourceFs := b.H.BaseFs.ProjectSourceFs
assetsFs := b.H.BaseFs.AssetsWithDuplicatesPreserved.Fs
mods := b.H.Configs.Modules
b.Assert(npm.Pack(sourceFs, assetsFs, mods), qt.IsNil)
pkg, err := afero.ReadFile(sourceFs, "packages/hugoautogen/package.json")
b.Assert(err, qt.IsNil)
b.Assert(string(pkg), qt.Contains, `"name": "hugoautogen"`)
b.Assert(string(pkg), qt.Contains, `"private": true`)
b.Assert(string(pkg), qt.Contains, `"version": "0.1.0"`)
// Hand-set fields survive a re-pack.
edited := strings.NewReplacer(
`"name": "hugoautogen"`, `"name": "@foo/hugoautogen"`,
`"version": "0.1.0"`, `"version": "1.2.3"`,
`"private": true`, `"private": false`,
).Replace(string(pkg))
b.Assert(afero.WriteFile(sourceFs, "packages/hugoautogen/package.json", []byte(edited), 0o666), qt.IsNil)
b.Assert(npm.Pack(sourceFs, assetsFs, mods), qt.IsNil)
pkg, err = afero.ReadFile(sourceFs, "packages/hugoautogen/package.json")
b.Assert(err, qt.IsNil)
b.Assert(string(pkg), qt.Contains, `"name": "@foo/hugoautogen"`)
b.Assert(string(pkg), qt.Contains, `"version": "1.2.3"`)
b.Assert(string(pkg), qt.Contains, `"private": false`)
}
func BenchmarkPackageFilesSum(b *testing.B) {
files := getPackageBuilderTestFiles()
bb := hugolib.Test(b, files)
+10 -5
View File
@@ -119,7 +119,8 @@ usePackageJSON="auto"
"strip-ansi": "7.2.0",
"to-pascal-case": "1.0.0"
},
"name": "script-mod_npm",
"name": "hugoautogen",
"private": true,
"version": "0.1.0"
}
-- golden1/package.json --
@@ -149,7 +150,8 @@ usePackageJSON="auto"
"strip-ansi": "7.2.0",
"to-pascal-case": "1.0.0"
},
"name": "script-mod_npm",
"name": "hugoautogen",
"private": true,
"version": "0.1.0"
}
-- golden3/packages/hugoautogen/package.json --
@@ -168,7 +170,8 @@ usePackageJSON="auto"
"strip-ansi": "7.2.0",
"to-pascal-case": "1.0.0"
},
"name": "script-mod_npm",
"name": "hugoautogen",
"private": true,
"version": "0.1.0"
}
-- golden4/packages/hugoautogen/package.json --
@@ -188,7 +191,8 @@ usePackageJSON="auto"
"strip-ansi": "7.2.0",
"to-pascal-case": "1.0.0"
},
"name": "script-mod_npm",
"name": "hugoautogen",
"private": true,
"version": "0.1.0"
}
-- golden5/packages/hugoautogen/package.json --
@@ -206,7 +210,8 @@ usePackageJSON="auto"
"strip-ansi": "7.2.0",
"to-pascal-case": "1.0.0"
},
"name": "script-mod_npm",
"name": "hugoautogen",
"private": true,
"version": "0.1.0"
}
-- go.mod --
@@ -42,7 +42,8 @@ go 1.20
"strip-ansi": "7.0.0",
"to-pascal-case": "1.0.0"
},
"name": "script-mod_npm__moduleorder",
"name": "hugoautogen",
"private": true,
"version": "0.1.0"
}
-- golden1/packages/hugoautogen/hugo_packagemeta.json --
@@ -37,7 +37,8 @@ path="github.com/gohugoio/hugoTestModule2"
"@babel/preset-env": "7.9.5",
"postcss-cli": "7.1.0"
},
"name": "script-mod_npm_withexisting",
"name": "hugoautogen",
"private": true,
"version": "0.1.0"
}
-- golden/package.json --