Repository navigation
yaml: pure-Go Psych loader + generic object dump → puppet apply exits cleanly - #40
Merged
Merged
Conversation
Make `puppet apply` exit with zero Error lines under rbgo. Three trailing errors are eliminated: - state.yaml "is corrupt": implement YAML.load / safe_load / load_file as a pure-Go Psych-subset parser (block + flow mappings/sequences, plain / quoted / literal-block scalars, symbols, ISO-8601 Time, bignums, !ruby/object: with &anchor/*alias) that round-trips what the emitter writes. - report to_yaml undefined: install Object#to_yaml and extend the emitter to serialise arbitrary objects as !ruby/object:Class with their ivars (recursively), plus !ruby/range, !ruby/class / !ruby/module, Regexp, and Set (as MRI's !ruby/object:Set). Shared/cyclic graph nodes are written once behind a YAML anchor. Complex and nil mapping keys use the explicit ?/: form. - "Could not save yaml : TypeError" (x2): the report graph now serialises, and FileSystem#replace_file no longer trips FileUtils.chown — implement FileUtils.chown / chown_R / chmod_R (reusing the fileChown seam; a no-op on Windows as in MRI). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- loader: parse flow collections before block-mapping detection; parse a
document-root / inline tagged object body at the correct indent; load
&anchor/*alias graphs; inline "tag {}" empty objects.
- dump: emit object/range/set body keys as plain identifiers (not quoted
strings); anchor shared plain collections; fix explicit-key ":" indent and
the standalone collection anchor spacing.
- add YAML load + object-dump test suites (round-trips vs MRI structure).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…fixes - add an internal-package test suite covering the scalar/flow/tag/anchor helpers, class resolution, countRefs graph walk and the encoder bodies. - remove unreachable defaults (dead Array/Hash cases in countRefs, the nil anchor-map guard, the openTag/tagBody trailing returns) so every branch is reachable. - fix a bare trailing "-" to load as nil (not an empty Hash) and the inline- first complex-key indentation (double "?" pad). Cross-package coverage is 100.0% with no function below 100%. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Makes
puppet applyexit with zeroError:lines under rbgo (the pure-Go CGO=0 Ruby). The previous milestone convergednotify/fileresources and emitted their Notices, but every run still printed three trailing errors:All three are gone.
Root causes & fixes
No YAML loader. rbgo had a Psych-compatible emitter but
YAML.load/safe_load/load_fileraisedNotImplementedError, soPuppet::Util::Yaml.load_file(state.yaml)failed and Puppet logged "state.yaml is corrupt; replacing" every run. Added a pure-Go Psych-subset parser (yaml_load.go): block + flow mappings/sequences, plain / single- / double-quoted / literal+folded block scalars, the Psych scalar keywords (null/bool/int/float/hex/bignum/ISO-8601 Time), symbols, and!ruby/object:/!ruby/symboltags with&anchor/*alias.YAML.dump(x)→YAML.loadround-trips the state/summary structures.No generic object serialization.
Report#to_yamlwas undefined andPsych.dumpof an arbitrary object raisedTypeError. AddedObject#to_yamland extended the emitter to serialise arbitrary objects as!ruby/object:Classwith their instance variables (recursively), plus!ruby/range,!ruby/class/!ruby/module,Regexp, andSet(MRI's!ruby/object:Set). Shared / cyclic graph nodes are emitted once behind a YAML anchor and aliased thereafter; complex and nil mapping keys use the explicit?/:form. The fullPuppet::Transaction::Reportgraph (~10k lines) now writes as syntactically-valid YAML (verified with MRIPsych.parse_file).Could not save yaml : TypeError(x2). Two causes: the report graph now serialises, andFileSystem#replace_fileno longer trips an unimplementedFileUtils.chownwhen rewriting an existingstate.yaml. ImplementedFileUtils.chown/chown_R/chmod_R(reusing the existingfileChownseam — a no-op on Windows, as in MRI).Verification
puppet apply -e 'notify {...}'run twice (state.yaml round-trip only shows on the 2nd run; the report write shows every run) — zeroError:lines both times. The MRI 4.0.5 oracle was used throughout forYAML.load(YAML.dump(x))round-trips andobj.to_yamlstructure. The twoWarning: Could not retrieve fact servername/serveriplines come from the intentionally-minimal facter probe shim, not rbgo.Tests / coverage
Cross-package coverage is 100.0% (the exact gate:
grep -v 100.0% | grep -v '^total'is empty), including all parse-error / edge branches. New Ruby-driven suites for load + object dump (matched to MRI structure) plus an internal-package suite for the scalar/flow/tag/anchor helpers, class resolution and the reference-graph walk.go vetclean,gofmtclean,GOOS=windowsbuild + vet clean, frozen-prelude drift test green.🤖 Generated with Claude Code