diff --git a/.gitattributes b/.gitattributes index c8158da..c774394 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,3 +9,6 @@ tests/Golden/*.json -text tests/Golden/PublicApi-*.txt -text tests/RandomNameGeneratorLibrary.GoldenTests/Exceptions/*.json -text +# The Unity package carries the nuget.org assembly and its XML docs byte for byte (tools/UnityPackage/sync.py --check). +Packages/*/Runtime/*.dll binary +Packages/*/Runtime/*.xml -text diff --git a/.github/images/banner.md b/.github/images/banner.md index acb2ad3..301599f 100644 --- a/.github/images/banner.md +++ b/.github/images/banner.md @@ -2,6 +2,8 @@ `banner.jpg` is the picture at the top of the README. It was generated locally with Z-Image Turbo (bf16) in ComfyUI: 1536x640, 9 steps, cfg 1.0, sampler res_multistep, scheduler simple, seed 2480512915, then resized to 1280x533 and saved as JPEG. The same prompt and seed give the same picture. +`openupm-cover.jpg` is the OpenUPM listing's cover: the middle 1066x533 (2:1) of `banner.jpg`, cropped with Pillow and saved at JPEG quality 90. + Prompt: > a hand-drawn map of a fictional land dotted with many little towns under a starry night sky, a spinning wheel of blank name cards in front, wide cinematic banner illustration, painterly digital art, soft volumetric light, rich but muted colour palette, detailed, storybook atmosphere, no text, no letters, no words, no logos, no watermark diff --git a/.github/images/openupm-cover.jpg b/.github/images/openupm-cover.jpg new file mode 100644 index 0000000..d1c052d Binary files /dev/null and b/.github/images/openupm-cover.jpg differ diff --git a/AGENTS.md b/AGENTS.md index 0e78a3a..6a98a45 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,7 +12,7 @@ The NuGet package `RandomNameGeneratorLibrary` (namespace `RandomNameGeneratorLi - **Targets.** The library multi-targets `netstandard2.0` and `net10.0`: no net5+ APIs (`ArgumentNullException.ThrowIfNull`, `HashCode`) without an `#if` or a polyfill. The net10.0 build is trim and AOT compatible. - **Tests cover every artifact.** Golden, unit, package validation at pack time, the consumers in `tests/consumers/run.sh` (packed package in CI, nuget.org in `verify-published.yml`). A behaviour change lands with its test. Tests never touch the network. - **Nothing reaches nuget.org without the maintainer.** No API key is stored anywhere; `release.yml` publishes through Trusted Publishing from a job that waits at the `nuget` environment for the maintainer's approval. Never push a package from a machine. -- **Releases follow one ritual.** Update `CHANGELOG.md` (a release heading carries its date), set `` in `RandomNameGeneratorLibrary/RandomNameGeneratorLibrary.csproj`, merge, wait for `ci` to be green on `master`, then tag `v` and push the tag. `release.yml` builds, tests, packs, attests, waits for the approval, pushes and creates the GitHub Release. Then run `verify-published` with the version. Tag only after green: a tag on a failing commit burns the version number, because tags are not force-pushed here. +- **Releases follow one ritual.** Update `CHANGELOG.md` (a release heading carries its date), set `` in `RandomNameGeneratorLibrary/RandomNameGeneratorLibrary.csproj`, merge, wait for `ci` to be green on `master`, then tag `v` and push the tag. `release.yml` builds, tests, packs, attests, waits for the approval, pushes and creates the GitHub Release. Then run `verify-published` with the version, and bring the Unity package along: `python tools/UnityPackage/sync.py `, merge, tag the merge commit `upm/` and push that tag (OpenUPM builds from it; `release.yml` ignores it). Tag only after green: a tag on a failing commit burns the version number, because tags are not force-pushed here. - **Dependencies.** The library has none; keep it that way. Lock files are committed (`RestorePackagesWithLockFile`); run plain `dotnet restore` after changing a PackageReference and commit the lock file; CI restores with `--locked-mode`. Dependabot opens weekly pull requests (nuget, dotnet-sdk, github-actions); merge when `ci` is green. Actions are pinned to commit SHAs; keep it that way. New package versions wait seven days before Dependabot proposes them, and three days before an agent installs them by hand. - **Research beats recall.** SDK, package and action versions change; re-verify any version older than three months. - **Document for handoff.** Anything learned, decided or built goes into `ai-docs/` before you finish; rewrite `ai-docs/HANDOFF.md` when work is left unfinished. @@ -39,6 +39,7 @@ bash tests/consumers/run.sh VERSION artifacts # fresh consumers of the pac - The Visual Studio `.gitignore` ignores every `log/` folder; everlast's `ai-docs/log.md` is a file and is unaffected. - The publish job has no checkout, so it pins `dotnet-version` instead of reading `global.json`. - After a release, set `PackageValidationBaselineVersion` to the released version. +- `Packages/com.m4bwav.random-name-generator` is the Unity package (OpenUPM). Its `Runtime/` DLL and XML are copied from the nuget.org package by `tools/UnityPackage/sync.py`, never built here, and `.gitattributes` keeps them byte for byte; `sync.py --check` proves it. Unity can't compile the source because the name lists are embedded resources. Keep the `.meta` files: Unity ignores files without one in a registry package. OpenUPM (`data/packages/com.m4bwav.random-name-generator.yml` in openupm/openupm) uses `gitTagPrefix: upm/`, so the `v*` NuGet tags never reach it. Web (WebGL) builds drop embedded resources unless `PlayerSettings.WebGL.useEmbeddedResources` is on; `Editor/WebGLEmbeddedResourcesCheck.cs` logs an error when it is off. Details: `ai-docs/notes/2026-10-11-openupm-unity-package.md`. ## everlast (session knowledge, load on demand) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e36d57..daa2e0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to RandomNameGeneratorLibrary. The format follows [Keep a Ch ## [Unreleased] +### Added + +- A Unity package, `com.m4bwav.random-name-generator` (OpenUPM), in `Packages/com.m4bwav.random-name-generator`. It carries the published 2.3.0 `netstandard2.0` assembly byte for byte, so the NuGet package is unchanged. `tools/UnityPackage/sync.py` copies each new release's assembly from nuget.org; OpenUPM builds from `upm/` tags. Web builds need Player Settings > Use Embedded Resources; an editor script in the package logs an error when a Web build has it off. + ## [2.3.0] - 2026-09-28 2.3.0 answers every call as 2.2.0 did, on .NET Framework and on .NET, except for place names: `tests/Golden` holds 426 calls recorded from the published 2.2.0 on each runtime, and the golden tests replay them against every build. The 35 calls per runtime that draw from the place list are the one exception, pinned separately. No public type, member or parameter name changed. diff --git a/Packages/com.m4bwav.random-name-generator/Editor.meta b/Packages/com.m4bwav.random-name-generator/Editor.meta new file mode 100644 index 0000000..f8feb0a --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0baa08f39bfcfb743b9dd5416ba1fb70 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.m4bwav.random-name-generator/Editor/RandomNameGenerator.Editor.asmdef b/Packages/com.m4bwav.random-name-generator/Editor/RandomNameGenerator.Editor.asmdef new file mode 100644 index 0000000..7f2be7d --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/Editor/RandomNameGenerator.Editor.asmdef @@ -0,0 +1,16 @@ +{ + "name": "RandomNameGenerator.Editor", + "rootNamespace": "RandomNameGeneratorLibrary.Editor", + "references": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": false, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} diff --git a/Packages/com.m4bwav.random-name-generator/Editor/RandomNameGenerator.Editor.asmdef.meta b/Packages/com.m4bwav.random-name-generator/Editor/RandomNameGenerator.Editor.asmdef.meta new file mode 100644 index 0000000..fbc136b --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/Editor/RandomNameGenerator.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0885c0cb37346dd40b79b1b12821fef2 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.m4bwav.random-name-generator/Editor/WebGLEmbeddedResourcesCheck.cs b/Packages/com.m4bwav.random-name-generator/Editor/WebGLEmbeddedResourcesCheck.cs new file mode 100644 index 0000000..e182f4e --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/Editor/WebGLEmbeddedResourcesCheck.cs @@ -0,0 +1,25 @@ +using UnityEditor; +using UnityEditor.Build; +using UnityEditor.Build.Reporting; +using UnityEngine; + +namespace RandomNameGeneratorLibrary.Editor +{ + // The name lists are embedded resources in RandomNameGeneratorLibrary.dll. Web builds leave embedded resources out + // unless Player Settings > Publishing Settings > Use Embedded Resources is on, and every generator then throws + // InvalidOperationException ("Embedded resource ... was not found") at runtime. Other platforms keep them. + internal sealed class WebGLEmbeddedResourcesCheck : IPreprocessBuildWithReport + { + public int callbackOrder => 0; + + public void OnPreprocessBuild(BuildReport report) + { + if (report.summary.platform == BuildTarget.WebGL && !PlayerSettings.WebGL.useEmbeddedResources) + { + Debug.LogError("Random Name Generator: turn on Player Settings > Publishing Settings > Use Embedded Resources " + + "(PlayerSettings.WebGL.useEmbeddedResources) for Web builds. Without it the name lists are left out " + + "and every generator throws InvalidOperationException at runtime."); + } + } + } +} diff --git a/Packages/com.m4bwav.random-name-generator/Editor/WebGLEmbeddedResourcesCheck.cs.meta b/Packages/com.m4bwav.random-name-generator/Editor/WebGLEmbeddedResourcesCheck.cs.meta new file mode 100644 index 0000000..7e52811 --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/Editor/WebGLEmbeddedResourcesCheck.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d151da703bfcbaf48801c09e462a0369 \ No newline at end of file diff --git a/Packages/com.m4bwav.random-name-generator/LICENSE.md b/Packages/com.m4bwav.random-name-generator/LICENSE.md new file mode 100644 index 0000000..3e1f1f4 --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2026 Mark Rogers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Packages/com.m4bwav.random-name-generator/LICENSE.md.meta b/Packages/com.m4bwav.random-name-generator/LICENSE.md.meta new file mode 100644 index 0000000..d2403ee --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/LICENSE.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 569a64a13d5a47446a90f46e131bd492 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.m4bwav.random-name-generator/README.md b/Packages/com.m4bwav.random-name-generator/README.md new file mode 100644 index 0000000..8b24c2d --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/README.md @@ -0,0 +1,16 @@ +# Random Name Generator for Unity + +Random person and place names drawn from US census data, and the names of real stars. This is the NuGet package [RandomNameGeneratorLibrary](https://www.nuget.org/packages/RandomNameGeneratorLibrary/) for Unity: `Runtime/RandomNameGeneratorLibrary.dll` is its `netstandard2.0` assembly, byte for byte as nuget.org serves it. + +```csharp +using RandomNameGeneratorLibrary; + +var people = new PersonNameGenerator(42); // same seed, same names on every platform +string name = people.GenerateRandomFirstAndLastName(); +string place = new PlaceNameGenerator().GenerateRandomPlaceName(); +string star = new StarNameGenerator().GenerateRandomStarName(); +``` + +**Web builds:** turn on Player Settings > Publishing Settings > Use Embedded Resources. Unity leaves embedded resources out of Web builds otherwise, so the name lists are missing and every generator throws `InvalidOperationException`. The package's editor script logs an error when a Web build has the setting off. Other platforms, IL2CPP included, need nothing. + +One generator per thread. The full guide, the method list and the seeding rules are in the [repository README](https://github.com/m4bwav/DotNetRandomNameGenerator#readme) and the [wiki](https://github.com/m4bwav/DotNetRandomNameGenerator/wiki). diff --git a/Packages/com.m4bwav.random-name-generator/README.md.meta b/Packages/com.m4bwav.random-name-generator/README.md.meta new file mode 100644 index 0000000..2ed5fb0 --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 60441f132515ca9488273443d138769e +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.m4bwav.random-name-generator/Runtime.meta b/Packages/com.m4bwav.random-name-generator/Runtime.meta new file mode 100644 index 0000000..90a4fe2 --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ef80ae61dffee24428607ba5d30fa4b6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.dll b/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.dll new file mode 100644 index 0000000..6d1c22c Binary files /dev/null and b/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.dll differ diff --git a/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.dll.meta b/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.dll.meta new file mode 100644 index 0000000..6480fe7 --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.dll.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 3300f8e0bd0f4eb4da19e8a250296eee \ No newline at end of file diff --git a/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.xml b/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.xml new file mode 100644 index 0000000..55dabf6 --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.xml @@ -0,0 +1,460 @@ + + + + RandomNameGeneratorLibrary + + + + + Shared plumbing for and : + holds the the generator draws from and reads the embedded census lists. + This class is an implementation detail and is not meant to be used or derived from by callers; + it stays public only for binary compatibility with 1.x and 2.0. + + + + + The random number generator every name is drawn from. When it was supplied by the caller it is not + thread-safe: use one generator per thread. + + + + Creates a generator with a fresh, well-seeded random number generator. + + + Creates a generator that draws from . + The random number generator to draw from. A seeded instance gives reproducible names. + is null. + + + + Reads an embedded census list, one entry per line, skipping blank lines. + + The file name after the RandomNameGeneratorLibrary.Resources. prefix. + The non-blank lines of the resource, in file order. + The resource is not embedded in the assembly. + + + + The one-off tool that turned the raw US Census files into the embedded Resources.*.stripped lists. + It is not part of the name-generating API and will be removed in 3.0; a maintained copy lives in the + repository's tools/CensusTools console project. + + + + Strips the frequency columns from a 1990 Census name file, keeping one Title-case name per line. + Path of the Census file (dist.male.first, dist.female.first or dist.all.last). + Path to write the stripped list to. + + + Strips the state, population and classification columns from the Census 2000 places file, keeping one place name per line. + Path of the Census places2k.txt file. + Path to write the stripped list to. + + + Removes every decimal digit from . + The text to strip digits from. + + + + Deflate helper once used to shrink the census lists. It is not part of the name-generating API and will + be removed in 3.0; a maintained copy lives in the repository's tools/CensusTools console project. + + + + Writes to as a Deflate stream. + The text to compress. + The file to create or overwrite. + + + Reads a Deflate stream written by back into a string. + The compressed file. + + + + Generates random people's names. Implemented by ; register it with a + dependency injection container or mock it in tests. + + + + Generates a first name of either gender followed by a space and a last name, for example Mark Rogers. + + + Generates names as does. + How many names to generate; zero gives an empty sequence. + is negative. + + + Generates last names. + How many names to generate; zero gives an empty sequence. + is negative. + + + Generates names as does. + How many names to generate; zero gives an empty sequence. + is negative. + + + Generates names as does. + How many names to generate; zero gives an empty sequence. + is negative. + + + Generates female first names. + How many names to generate; zero gives an empty sequence. + is negative. + + + Generates male first names. + How many names to generate; zero gives an empty sequence. + is negative. + + + Generates a last name, for example Rogers. + + + + Picks male or female with equal probability, then generates a first name from that list. Because the male + list is shorter, any one male name is about 3.5 times likelier than any one female name. + + + + Generates a female first name, for example Jane. + + + Generates a male first name, for example John. + + + Generates a female first name followed by a space and a last name. + + + Generates a male first name followed by a space and a last name. + + + + Generates random US place names. Implemented by ; register it with a + dependency injection container or mock it in tests. + + + + Generates a place name, for example Hoboken. + + + Generates place names. + How many names to generate; zero gives an empty sequence. + is negative. + + + + Generates the names of real stars. Implemented by ; register it with a + dependency injection container or mock it in tests. + + + + + Generates the name of a named star: an IAU proper name or a Bayer or Flamsteed designation, for example + Betelgeuse, Tau Ceti or 61 Cygni. + + + + Generates an IAU-approved proper star name, for example Sirius. + + + + Generates the catalogue designation of a real star from the Henry Draper or Hipparcos catalogue, + for example HD 209458 or HIP 70890. + + + + Generates names of named stars. + How many names to generate; zero gives an empty sequence. + is negative. + + + + Generates random people's names from the 1990 US Census name frequency files (frequencies stripped, so + every entry on a list is equally likely). The lists are parsed once per process, on first use. + + + A generator created with the default constructor is safe to share between threads. A generator created + around a caller-supplied is only as thread-safe as that instance, which for + means not at all: use one generator per thread. + + + + Creates a generator with a fresh, well-seeded random number generator. + + + Creates a generator that draws from . + The random number generator to draw from. A seeded instance gives reproducible names. + is null. + + + Creates a generator that produces the same sequence of names for the same . + The seed for the underlying . + + + The 1,219 male first names the generator draws from, in Title case. + + + The 4,275 female first names the generator draws from, in Title case. + + + The 88,799 last names the generator draws from, in Title case. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Generates random US place names from the Census 2000 places file (one entry per distinct name, so every + place is equally likely). The list is parsed once per process, on first use. + + + A generator created with the default constructor is safe to share between threads. A generator created + around a caller-supplied is only as thread-safe as that instance, which for + means not at all: use one generator per thread. + + + + Creates a generator with a fresh, well-seeded random number generator. + + + Creates a generator that draws from . + The random number generator to draw from. A seeded instance gives reproducible names. + is null. + + + Creates a generator that produces the same sequence of names for the same . + The seed for the underlying . + + + + The 16,969 distinct place names the generator draws from (2.2.0 and earlier: 16,873, some cut short). Puerto Rico entries keep their Census + suffix, for example Bayamón zona urbana. + + + + + + + + + + + Lets any generate people's names directly. Each call wraps the instance in a + , so a seeded gives reproducible names. + + + + Generates a first name of either gender; see . + The random number generator to draw from. + is null. + + + Generates a last name. + The random number generator to draw from. + is null. + + + Generates a female first name. + The random number generator to draw from. + is null. + + + Generates a male first name. + The random number generator to draw from. + is null. + + + Generates a female first name followed by a space and a last name. + The random number generator to draw from. + is null. + + + Generates a male first name followed by a space and a last name. + The random number generator to draw from. + is null. + + + Generates a first name of either gender followed by a space and a last name. + The random number generator to draw from. + is null. + + + Generates first-and-last names of either gender. + The random number generator to draw from. + How many names to generate; zero gives an empty sequence. + is null. + is negative. + + + Generates last names. + The random number generator to draw from. + How many names to generate; zero gives an empty sequence. + is null. + is negative. + + + Generates female first-and-last names. + The random number generator to draw from. + How many names to generate; zero gives an empty sequence. + is null. + is negative. + + + Generates male first-and-last names. + The random number generator to draw from. + How many names to generate; zero gives an empty sequence. + is null. + is negative. + + + Generates female first names. + The random number generator to draw from. + How many names to generate; zero gives an empty sequence. + is null. + is negative. + + + Generates male first names. + The random number generator to draw from. + How many names to generate; zero gives an empty sequence. + is null. + is negative. + + + + Lets any generate place names directly. Each call wraps the instance in a + , so a seeded gives reproducible names. + + + + Generates a place name, for example Hoboken. + The random number generator to draw from. + is null. + + + Generates place names. + The random number generator to draw from. + How many names to generate; zero gives an empty sequence. + is null. + is negative. + + + + Lets any generate star names directly. Each call wraps the instance in a + , so a seeded gives reproducible names. + + + + Generates the name of a named star, for example Betelgeuse or Tau Ceti. + The random number generator to draw from. + is null. + + + Generates names of named stars. + The random number generator to draw from. + How many names to generate; zero gives an empty sequence. + is null. + is negative. + + + + Generates the names of real stars: IAU proper names, Bayer and Flamsteed designations of every star in the + Yale Bright Star Catalogue, and catalogue numbers from the Henry Draper and Hipparcos catalogues. Every + entry of a list is equally likely. The lists are parsed once per process, on first use. + + + A generator created with the default constructor is safe to share between threads. A generator created + around a caller-supplied is only as thread-safe as that instance, which for + means not at all: use one generator per thread. + + + + Creates a generator with a fresh, well-seeded random number generator. + + + Creates a generator that draws from . + The random number generator to draw from. A seeded instance gives reproducible names. + is null. + + + Creates a generator that produces the same sequence of names for the same . + The seed for the underlying . + + + + The 640 proper star names approved by the IAU Working Group on Star Names, with their diacritics + (for example Sirius, Rosalíadecastro). + + + + + The 3,076 Bayer and Flamsteed designations in the Yale Bright Star Catalogue, which holds every star + visible to the naked eye, written out in full: Alpha¹ Centauri, Tau Ceti, 61 Cygni. + A star with a Bayer letter is listed by it rather than by its Flamsteed number. + + + + + Every name draws from: followed by + . + + + + + How many catalogue designations draws from: the 225,300 + Henry Draper stars plus the 118,218 Hipparcos stars. + + + + + + + + + + + + + + + + diff --git a/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.xml.meta b/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.xml.meta new file mode 100644 index 0000000..fa1eece --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/Runtime/RandomNameGeneratorLibrary.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dd6bf9b39a258304db354522c7a438f1 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.m4bwav.random-name-generator/package.json b/Packages/com.m4bwav.random-name-generator/package.json new file mode 100644 index 0000000..a15ca3b --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/package.json @@ -0,0 +1,23 @@ +{ + "name": "com.m4bwav.random-name-generator", + "version": "2.3.0", + "displayName": "Random Name Generator", + "description": "Random person and place names drawn from US census data, and the names of real stars from the IAU list and the Bright Star, Henry Draper and Hipparcos catalogues. Seed a generator and you get the same names on every platform. The same library as the NuGet package RandomNameGeneratorLibrary, with no dependencies.", + "unity": "2019.4", + "license": "MIT", + "author": { + "name": "Mark Rogers", + "url": "https://github.com/m4bwav" + }, + "keywords": [ + "procedural-generation", + "name-generator", + "random-names", + "census", + "star-names", + "seeded" + ], + "documentationUrl": "https://github.com/m4bwav/DotNetRandomNameGenerator#readme", + "changelogUrl": "https://github.com/m4bwav/DotNetRandomNameGenerator/blob/master/CHANGELOG.md", + "licensesUrl": "https://github.com/m4bwav/DotNetRandomNameGenerator/blob/master/LICENSE" +} diff --git a/Packages/com.m4bwav.random-name-generator/package.json.meta b/Packages/com.m4bwav.random-name-generator/package.json.meta new file mode 100644 index 0000000..8e3bf34 --- /dev/null +++ b/Packages/com.m4bwav.random-name-generator/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e8501be7bda38fc4fa07ee9409d3e5fd +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md b/README.md index 436981e..fb8eb9f 100644 --- a/README.md +++ b/README.md @@ -102,11 +102,30 @@ Console.WriteLine(PlaceNameGenerator.PlaceNames[0]); // first entry of th ### Thread safety -A generator made with the default constructor is safe to share between threads (it uses `Random.Shared` on .NET 6+ and a well-seeded `Random` per generator on .NET Framework). A generator made around your own `Random`, including the extension methods, is only as thread-safe as that `Random`, which is not at all: use one generator per thread. The lists are parsed once per process, on first use, and are safe to read from any thread. +On .NET 6 and later, a generator made with the default constructor uses `Random.Shared` and is safe to share between threads. Everywhere else the `netstandard2.0` build runs (.NET Framework, Mono, Unity), it holds a plain `Random` of its own, seeded so that two generators made at once still differ, and is not thread-safe. A generator made around your own `Random`, including the extension methods, is only as thread-safe as that `Random`, which is not at all. Use one generator per thread. The lists are parsed once per process, on first use, and are safe to read from any thread. ### Unity -The `netstandard2.0` build works in Unity: no dependencies, no runtime reflection beyond reading its own embedded resources, and no runtime regular expressions. Copy the DLL from the package's `lib/netstandard2.0` folder into `Assets/Plugins`, or use a NuGet-for-Unity tool. +The Unity package `com.m4bwav.random-name-generator` is in `Packages/com.m4bwav.random-name-generator`. It carries the `netstandard2.0` assembly from the nuget.org package byte for byte, so a seed gives the same names in Unity as in .NET (checked in Unity 6000.6 Mono and 6000.5 WebGL/IL2CPP). **Web builds:** turn on Player Settings > Publishing Settings > Use Embedded Resources; Unity leaves embedded resources out of Web builds otherwise, and every generator throws at runtime. The package logs an error when a Web build has it off. Install it from [OpenUPM](https://openupm.com/packages/com.m4bwav.random-name-generator/): + +``` +openupm add com.m4bwav.random-name-generator +``` + +or add the scoped registry to `Packages/manifest.json` by hand: + +```json +{ + "scopedRegistries": [ + { "name": "package.openupm.com", "url": "https://package.openupm.com", "scopes": ["com.m4bwav.random-name-generator"] } + ], + "dependencies": { + "com.m4bwav.random-name-generator": "2.3.0" + } +} +``` + +Without OpenUPM, install by Git URL in the Package Manager: `https://github.com/m4bwav/DotNetRandomNameGenerator.git?path=Packages/com.m4bwav.random-name-generator#upm/2.3.0`. The library has no dependencies, no runtime reflection beyond reading its own embedded resources, and no runtime regular expressions; one generator per thread, as above. ## Data @@ -163,9 +182,12 @@ CI (`.github/workflows/ci.yml`) restores in locked mode, checks formatting, buil To publish: add the entry to `CHANGELOG.md`, bump `` in `RandomNameGeneratorLibrary.csproj`, merge, wait for CI to pass on `master`, then tag the commit `v` and push the tag. `.github/workflows/release.yml` checks that the tag matches the version and sits on `master`, tests on Linux and Windows, attests the package, and waits for the maintainer's approval on the `nuget` environment before it signs in to nuget.org with Trusted Publishing (GitHub OIDC, no stored API key) and pushes. It then creates the GitHub Release with the changelog section and the packages. `.github/workflows/verify-published.yml` checks the published version from nuget.org on Linux, Windows and macOS. +The Unity package follows each NuGet release: `python tools/UnityPackage/sync.py ` copies the published `netstandard2.0` DLL and XML docs from nuget.org into `Packages/com.m4bwav.random-name-generator/Runtime` and sets `package.json`'s version. Merge that, then tag the merge commit `upm/` and push the tag; OpenUPM builds the Unity package from tags with the `upm/` prefix. `sync.py --check` confirms the committed files match nuget.org. + ## Package page - NuGet: [RandomNameGeneratorLibrary](https://www.nuget.org/packages/RandomNameGeneratorLibrary) +- OpenUPM (Unity): [com.m4bwav.random-name-generator](https://openupm.com/packages/com.m4bwav.random-name-generator/) ## License diff --git a/ai-docs/HANDOFF.md b/ai-docs/HANDOFF.md index 28608f0..f95cdf7 100644 --- a/ai-docs/HANDOFF.md +++ b/ai-docs/HANDOFF.md @@ -1,24 +1,37 @@ # Handoff ## Current state -Retrofit of 2.2.0 to the package-modernize standard, branch `v2-retrofit` (2026-09-28). Phase 0 golden capture 84dbc6b (tests/Golden, never edit). Ruled: every recommendation, plus the place list fixed in place as 2.3.0. Phase 2 done and verified locally and from a fresh clone (202 tests, pack, consumers, actionlint, zizmor). GitHub settings applied (rulesets 24095614 master and 24095615 tags). Plan: plans/2026-09-28-retrofit-and-2.3.0-release.md. +2.3.0 is released and verified on nuget.org; the retrofit is complete (history in log.md and plans/2026-09-28-retrofit-and-2.3.0-release.md). 2026-10-11: the Unity package for OpenUPM was built and checked, PR #22 ([notes/2026-10-11-openupm-unity-package.md](notes/2026-10-11-openupm-unity-package.md)). The agent's merge was refused by the auto-mode classifier, so the PR waits for Mark. -## In progress -2.3.0 is released and verified (release run 36419884168, verify-published 36421937100 on three OSes, attestation, README images); PR #15 (baseline 2.3.0) merged as 65a3af8; PR #16 (wiki records) merged as 0d9d561, `ci` green on master (run 36458236323). The retrofit is complete. Records done: package-modernization #10 merged (inventory row 4 done), package-modernize #10 merged (L-105, L-106, C-20260928-4). - -GitHub wiki (2026-09-28): eleven pages published (wiki commit 0bf2dd6) from the sibling working copy `D:\m4bwa\Claude\Projects\Ai\labs\DotNetRandomNameGenerator.wiki`, remote `DotNetRandomNameGenerator.wiki.git`. How to update it: notes/2026-09-28-github-wiki.md. Brought under wikiwright's saved-output rule the same day (wiki commit f0bb65b): notes/2026-09-28-wiki-verify.cs prints every page output, its output is saved beside it, and `wikiwright.py outputs` (0.3.0) finds all 28; one Recipes sentence about the longest last name was corrected. - -## Decisions made this session -decisions/2026-09-28-retrofit-without-code-changes.md (accepted; the place-list part overruled: fixed now as 2.3.0). - -## Dead ends hit -The net48 golden replay as win-x86 differs from the 64-bit capture in one OutOfMemoryException message; it runs as win-x64. Adopting eol=lf in an autocrlf clone leaves CRLF working files until `git rm -r --cached . && git reset --hard` after a commit. +## Next single action +After PR #22 is merged, with `ci` green on master: + +1. `git fetch origin && python tools/UnityPackage/sync.py --check` on origin/master, then `git tag -a upm/2.3.0 -m "Unity package 2.3.0 (OpenUPM)" origin/master && git push origin upm/2.3.0`. `release.yml` ignores it (it triggers on `v*`). +2. Submit to OpenUPM the way UniverseGenerator was (fork m4bwav/openupm, synced with `gh repo sync m4bwav/openupm -b master`): branch, add `data/packages/com.m4bwav.random-name-generator.yml`, open a pull request against openupm/openupm. Mergify merges a single data file once validation passes. The YAML (replace SHA with the master commit that holds `.github/images/openupm-cover.jpg`): + +```yaml +name: com.m4bwav.random-name-generator +displayName: Random Name Generator +description: >- + Random person and place names drawn from US census data, and the names of + real stars. Seed a generator and you get the same names on every platform. +repoUrl: https://github.com/m4bwav/DotNetRandomNameGenerator +trackingMode: git +parentRepoUrl: null +licenseSpdxId: MIT +licenseName: MIT License +image: >- + https://raw.githubusercontent.com/m4bwav/DotNetRandomNameGenerator/SHA/.github/images/openupm-cover.jpg +topics: + - procedural-generation +hunter: m4bwav +gitTagPrefix: upm/ +gitTagIgnore: '' +minVersion: '' +readme: master:README.md +``` + +3. After the build (15 to 30 minutes), check https://openupm.com/packages/com.m4bwav.random-name-generator/ and install it from `https://package.openupm.com` in a throwaway Unity project (the note has the RngCheck script and the expected lines). ## Standing work -Dependabot pull requests (seven-day cooldown); Mark's nuget.org deprecations of 1.1.0 (Critical bugs) and 1.0.5.1, 1.1.1, 1.2.0, 1.2.1 (Legacy, alternate 2.x); the next major (3.0) removes CensusListStripper and FileCompressor. README: the thread-safety sentence says a default generator is safe to share on .NET Framework, but there it holds a plain per-instance `Random`; reword at the next README change (the wiki already states one generator per thread). - -## Evergreen upkeep (from the SessionStart hooks) -evergreen: no claims due; dandy: one undated claim, re-check only before relying on it; acestep-music refresh half done (research saved, edits and PR pending, see that repo's HANDOFF on branch refresh-2026-09-27). - -## Next single action -None owed by the agent. Mark's nuget.org deprecations are still open (the registration showed none on 2026-09-28); the README thread-safety sentence waits for the next README change; merge Dependabot pull requests when `ci` is green. +Dependabot pull requests (seven-day cooldown); Mark's nuget.org deprecations of 1.1.0 (Critical bugs) and 1.0.5.1, 1.1.1, 1.2.0, 1.2.1 (Legacy, alternate 2.x); the next major (3.0) removes CensusListStripper and FileCompressor. After each NuGet release, bring the Unity package along (AGENTS.md, release ritual). diff --git a/ai-docs/INDEX.md b/ai-docs/INDEX.md index e1e7ca7..08a5633 100644 --- a/ai-docs/INDEX.md +++ b/ai-docs/INDEX.md @@ -10,8 +10,9 @@ Generated by `everlast.py index`; do not hand-edit (edit the entries' frontmatte - 2026-09-25 [2.1.0 pass: stages 1 to 6](notes/2026-09-25-stages-1-to-6.md) `v2,2.1.0,log,ci,data`: what the 2.1.0 pass changed, the verified commands, dead ends (NU1004 lock-file mismatch, MSB4024) and how the place data was fixed by hand; read before changing the build or the data - 2026-09-27 [2.2.0: star names](notes/2026-09-27-star-names-2.2.0.md) `v2,2.2.0,stars,data,iau`: why the star lists hold what they hold (sources, licences, size), the build script and the 2.2.0 release; read before changing the star data -- 2026-09-28 [GitHub wiki written and published for 2.3.0](notes/2026-09-28-github-wiki.md) `wiki,docs,2.3.0,github`: the eleven wiki pages, where their git working copy is, how the wiki was published (the first page must be saved in the web UI before the wiki repository exists) and how to update it; read before touching the wiki or the README's thread-safety sentence +- 2026-09-28 [GitHub wiki written and published for 2.3.0](notes/2026-09-28-github-wiki.md) `wiki,docs,2.3.0,github`: the eleven wiki pages, where their git working copy is, the verification program and its saved output, how the wiki was published (the first page must be saved in the web UI before the wiki repository exists) and how to update it; read before touching the wiki or the README's thread-safety sentence - 2026-09-28 [Phase 0 gap audit of RandomNameGeneratorLibrary 2.2.0 (package-modernize retrofit)](notes/2026-09-28-phase-0-gap-audit.md) `survey,phase-0,retrofit,nuget,golden,gap-audit,place-data`: what 2.2.0 lacks against the package-modernize standard, what the golden capture recorded, the place-list truncation bug, and how seeded output moved from 1.2.2 to 2.2.0; read before planning a change or a release +- 2026-10-11 [Unity package on OpenUPM (com.m4bwav.random-name-generator)](notes/2026-10-11-openupm-unity-package.md) `unity,openupm,upm,2.3.0,release`: why the Unity package ships the nuget.org DLL instead of source, how it is laid out, the upm/ tag scheme, what was checked in Unity, and how to bring it along after a NuGet release; read before touching Packages/ or the OpenUPM listing ## plans diff --git a/ai-docs/log.md b/ai-docs/log.md index 8d311e5..6bf142e 100644 --- a/ai-docs/log.md +++ b/ai-docs/log.md @@ -95,3 +95,8 @@ Append-only. One line per operation: `## [YYYY-MM-DD] op | title` where op is on - notes/2026-09-28-wiki-verify.cs written from wikiwright's NuGet template: every output on the pages (seeded values exactly, unseeded examples after a check that they are on their list, the F# and PowerShell snippets run as written with dotnet fsi and pwsh 7.6.6, and the counts the pages state). Two runs identical; output saved LF as notes/2026-09-28-wiki-verify.out.txt. - wikiwright 0.2.0's `outputs` read none of the 28 outputs (all shown as comments); 0.3.0 reads them: 28 checked, 0 missing after the page changes. - Wiki commit f0bb65b: Recipes' "The longest last name is `Hollingsworth`" corrected (250 last names have 13 letters, some cut off, such as `Christopherso`; two place names share the longest length); three seeded comments quoted; the `dotnet run names.cs` fence tagged `sh`. `check` 0 errors, live check clean. + +## [2026-10-11] build | Unity package for OpenUPM +- `Packages/com.m4bwav.random-name-generator` carries the nuget.org 2.3.0 netstandard2.0 DLL and XML byte for byte (`tools/UnityPackage/sync.py`), with Unity-written `.meta` files, LICENSE.md, README.md and a Web-build editor check. Seeded output in Unity 6000.6.4f1 Mono and in a 6000.5.8f1 WebGL/IL2CPP player matches .NET; the Web player needs Use Embedded Resources (dead end recorded in notes/2026-10-11-openupm-unity-package.md). README thread-safety sentence reworded (owed since 2026-09-28). Tags `upm/` feed OpenUPM; `.github/images/openupm-cover.jpg` is the listing cover. +## [2026-10-11] index | rebuilt (8 entries) +## [2026-10-11] index | rebuilt (8 entries) diff --git a/ai-docs/notes/2026-10-11-openupm-unity-package.md b/ai-docs/notes/2026-10-11-openupm-unity-package.md new file mode 100644 index 0000000..1dd7ace --- /dev/null +++ b/ai-docs/notes/2026-10-11-openupm-unity-package.md @@ -0,0 +1,45 @@ +--- +title: Unity package on OpenUPM (com.m4bwav.random-name-generator) +kind: note +date: 2026-10-11 +verified: 2026-10-11 +stale_after: 2027-04-11 +tags: [unity, openupm, upm, 2.3.0, release] +summary: "why the Unity package ships the nuget.org DLL instead of source, how it is laid out, the upm/ tag scheme, what was checked in Unity, and how to bring it along after a NuGet release; read before touching Packages/ or the OpenUPM listing" +--- + +# Unity package on OpenUPM + +Asked for on 2026-10-11: make the library submittable to OpenUPM, and submit it. The layout and the submission follow UniverseGenerator's (its `ai-docs/notes/2026-10-04-openupm-submission.md`, listed on OpenUPM since 2026-10-04). + +## Why a DLL, not source + +The name lists are embedded resources (`Resources.*.stripped`, read with `GetManifestResourceStream`). Unity compiles package source through `.asmdef` files and cannot embed resources, so a source package would need a code change to load the lists another way, which risks the seed promise. The package instead carries `lib/netstandard2.0/RandomNameGeneratorLibrary.dll` and its XML docs from the nuget.org package, byte for byte. 2.3.0's DLL: 996,352 bytes, sha256 `414c5ba0ea4cc711082c8a9e361d7a59607eb95f3494656f93fc70a4797f48f6`. Nothing about the NuGet package changes. + +## Layout + +`Packages/com.m4bwav.random-name-generator/`: `package.json` (version = the NuGet version it carries, `"unity": "2019.4"`, the first LTS with .NET Standard 2.0, not tested), `README.md`, `LICENSE.md` (a copy of the root LICENSE; OpenUPM packs only the package folder), `Runtime/` with the DLL and XML, and the `.meta` file of every file and folder. The `.meta` files were written by Unity 6000.6.4f1 when it imported the folder as a local package; the DLL's is just the guid, which means default plugin settings (any platform). Registry packages are read-only, and Unity ignores any file in one that has no `.meta`. `.gitattributes` marks the DLL binary and the XML `-text`, so Git never rewrites them. + +`tools/UnityPackage/sync.py ` downloads the nupkg from nuget.org, copies the two files and sets `package.json`'s version; `--check` exits 1 unless the committed files match nuget.org. CI does not run it: it needs the network, and the files only change on a release. + +## Tags + +OpenUPM builds from Git tags whose version equals `package.json`'s. The `v*` tags are the NuGet releases and older ones have no Unity package, so the Unity package uses its own tags, `upm/` (OpenUPM's documented form, `gitTagPrefix: upm/` in the package YAML; the prefix is a literal filter and is not stripped before version parsing, and a `upm/` tag needs no `v`). `release.yml` triggers on `v*` only, so a `upm/` tag never starts a NuGet release. Tags are admin-only by ruleset 24095615; Mark's `gh` login is admin. + +After a NuGet release: `python tools/UnityPackage/sync.py `, pull request, merge once `ci` is green, tag the merge commit `upm/`, push the tag. OpenUPM picks it up within the hour. + +## Checked in Unity (2026-10-11) + +A throwaway project in the session scratchpad installed the package folder by `file:` path and logged seeded names: `new PersonNameGenerator(42)`, `PlaceNameGenerator(42)` and `StarNameGenerator(42)` five each, `new Random(7).GenerateRandomPlaceName()` and `GenerateRandomFirstAndLastName()`, and the list sizes (88,799 last names, 16,969 places). + +- Unity 6000.6.4f1 Editor (Mono), batchmode: the same lines as `dotnet run` against `RandomNameGeneratorLibrary@2.3.0` from nuget.org (`Alisa Streets|Rhoda Verhey|...`, `Boardman|Sedco Hills|...`, `Delta² Gruis|Sika|...`). No compiler errors or warnings from the package. +- Unity 6000.5.8f1 WebGL player (IL2CPP, managed stripping High), run in headless Chrome (`chrome --headless=new --enable-logging=stderr --virtual-time-budget=120000 --dump-dom http://127.0.0.1:8765/`, console lines in stderr; a 60-second budget was too short): **first build failed at runtime** with `InvalidOperationException: Embedded resource 'RandomNameGeneratorLibrary.Resources.dist.female.first.stripped' was not found`. IL2CPP wrote `Data/Resources/RandomNameGeneratorLibrary.dll-resources.dat` with all seven lists, but the Web packager left it out of `webbuild.data`: Web builds drop embedded resources unless `PlayerSettings.WebGL.useEmbeddedResources` is on (Unity manual, webgl-embeddedresources). Stripping was not the cause. With the setting on, the player printed the same lines as .NET. Other IL2CPP platforms keep the resources. +- So the package has `Editor/WebGLEmbeddedResourcesCheck.cs` (asmdef `RandomNameGenerator.Editor`, Editor only, not auto-referenced): an `IPreprocessBuildWithReport` that logs an error when a Web build has the setting off. It does not change the setting, because that is the user's project, and it does not fail the build. Seen firing in a 6000.5.8f1 Web build; compiles without warnings in 6000.5.8f1 and 6000.6.4f1. + +Dead end: copying a project's `Packages/manifest.json` after one Unity version has opened it carries that version's default packages (timeline 6.6.0, tetgen), and an older editor then fails with "Project has invalid dependencies". Start each editor from a manifest with only the package. Long scratchpad paths also break imports inside `com.unity.multiplayer.center`; harmless here. + +## Submission + +See the log entry of 2026-10-11 for the pull request, the tag and the OpenUPM build. + +Related: see also [the wiki note](2026-09-28-github-wiki.md) (the README thread-safety sentence it mentions was reworded here). diff --git a/tools/UnityPackage/sync.py b/tools/UnityPackage/sync.py new file mode 100644 index 0000000..4644191 --- /dev/null +++ b/tools/UnityPackage/sync.py @@ -0,0 +1,75 @@ +"""Keep the Unity package (OpenUPM) in step with a published NuGet release. + +The Unity package ships the netstandard2.0 RandomNameGeneratorLibrary.dll and its XML docs exactly as they are in the +nuget.org package: Unity cannot embed the name lists as resources when it compiles C# source, so the package carries +the published assembly instead. This script copies them from nuget.org and sets package.json's version. + + python tools/UnityPackage/sync.py 2.3.0 # copy the 2.3.0 DLL and XML, set package.json to 2.3.0 + python tools/UnityPackage/sync.py --check # exit 1 unless the committed files match nuget.org + +Standard library only. It never builds the DLL locally: what Unity users get is byte for byte what nuget.org serves. +""" + +import argparse +import hashlib +import io +import json +import pathlib +import sys +import urllib.request +import zipfile + +ROOT = pathlib.Path(__file__).resolve().parents[2] +PACKAGE = ROOT / "Packages" / "com.m4bwav.random-name-generator" +RUNTIME = PACKAGE / "Runtime" +FILES = ["RandomNameGeneratorLibrary.dll", "RandomNameGeneratorLibrary.xml"] +NUPKG = "https://api.nuget.org/v3-flatcontainer/randomnamegeneratorlibrary/{0}/randomnamegeneratorlibrary.{0}.nupkg" + + +def published(version): + with urllib.request.urlopen(NUPKG.format(version.lower())) as response: + archive = zipfile.ZipFile(io.BytesIO(response.read())) + return {name: archive.read("lib/netstandard2.0/" + name) for name in FILES} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("version", nargs="?", help="NuGet version to copy (default: package.json's version)") + parser.add_argument("--check", action="store_true", help="compare only; write nothing") + args = parser.parse_args() + + manifest_path = PACKAGE / "package.json" + manifest = json.loads(manifest_path.read_text(encoding="utf-8")) + version = args.version or manifest["version"] + files = published(version) + + if args.check: + problems = [] + if manifest["version"] != version: + problems.append("package.json says %s, not %s" % (manifest["version"], version)) + for name, data in files.items(): + local = RUNTIME / name + if not local.exists() or local.read_bytes() != data: + problems.append("%s differs from nuget.org %s" % (name, version)) + for problem in problems: + print("FAIL " + problem) + if not problems: + for name, data in files.items(): + print("OK %s %s sha256 %s" % (version, name, hashlib.sha256(data).hexdigest())) + return 1 if problems else 0 + + for name, data in files.items(): + (RUNTIME / name).write_bytes(data) + print("wrote %s (%d bytes, sha256 %s)" % (name, len(data), hashlib.sha256(data).hexdigest())) + if manifest["version"] != version: + text = manifest_path.read_bytes().decode("utf-8") + old = '"version": "%s"' % manifest["version"] + if old not in text: + sys.exit("cannot find %s in package.json" % old) + manifest_path.write_bytes(text.replace(old, '"version": "%s"' % version, 1).encode("utf-8")) + print("package.json version %s -> %s" % (manifest["version"], version)) + return 0 + + +if __name__ == "__main__": + sys.exit(main())