summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-03-14Resolve multi-word agent names in file DSLdevelopPaul Buetow
2026-03-14Validate agent configs during dry runsPaul Buetow
2026-03-14Use active DSL registry for Resource.findPaul Buetow
2026-03-14Add agent-backed file processing DSLPaul Buetow
2026-03-02bump version to 0.1.20.1.2mainPaul Buetow
2026-03-02Merge branch 'develop'Paul Buetow
Includes security fixes, bug fixes, and code quality refactors: - Fix command injection in DNFPackageManager (system() multi-arg form) - Fix backup_resursively! typo (latent NoMethodError) - Add error handling to DNFPackageManager (CommandFailed + run_dnf!) - Split file.rb monolith into per-class files - Extract DryRun concern (SRP), narrow BasicFile interface (ISP) - Extract register_keyword DSL helper (DRY) - Replace ObjectSpace scan with inherited-hook class registry - Defer Options.parse! and Config.load! to application entry point - Add Justfiles to all example directories
2026-03-02add Justfiles for all examplesPaul Buetow
Each example directory gets a Justfile with run/dry/debug recipes. The rake and gem examples also include a setup recipe for bundle install. The cli example adds a hosts recipe for the --hosts flag. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01bugfix/refactor: add error handling to DNFPackageManager shell commandsPaul Buetow
system() returns false/nil on failure but the original code ignored the return value, silently swallowing dnf errors. Add a private run_dnf! helper that checks the return value and raises DNFPackageManager::CommandFailed with the dnf exit code on failure. Replace the one-liner methods with full method bodies that delegate to run_dnf!. Also fix two latent constant-resolution bugs: - Use $? instead of $CHILD_STATUS (the latter requires `require 'English'` and is always nil without it) - Use ::File instead of File in Package#initialize to avoid resolving to RCM::File once file.rb is loaded Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01refactor: defer Config loading — add explicit Config.load! methodPaul Buetow
Loading config.toml at module eval time (during require) runs before the application's working directory is set, can slow down tests that don't use config at all, and gives no way to reload between calls. Move the load logic into Config.load! (mirrors the Options.parse! pattern added in the previous commit). The module body now just initialises @@config to {}. Call Config.load! alongside Options.parse! at the top of configure() so all entry points reload from the correct directory. Also qualify File as ::File inside the RCM module to avoid resolving it as RCM::File once the keyword files are loaded. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01refactor: defer Options parsing — add explicit Options.parse! methodPaul Buetow
Parsing ARGV at module eval time (during require) is fragile: it runs before the application is ready, can pick up test-runner flags, and bleeds stale values across repeated configure calls in tests. Move the OptionParser setup and ARGV slicing into Options.parse!. The module body now only sets safe defaults. parse! resets to defaults before each parse so state cannot accumulate across calls. Call Options.parse! once at the top of configure() in dsl.rb so all entry points (scripts, Rake tasks) still receive parsed options without any caller needing to know about the details. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01refactor: replace ObjectSpace scan with inherited-hook registryPaul Buetow
ResourceDependencies#initialize iterated every live object in the Ruby heap (ObjectSpace.each_object(Class)) to discover Resource subclasses, which is O(heap), non-deterministic, and load-order-dependent (subclasses loaded after an instance was created were invisible to it). Add Resource.inherited + @@subclass_names so each subclass self-registers at load time. ResourceDependencies#initialize now just assigns the shared (frozen) registry reference instead of scanning ObjectSpace. Benefits: - O(1) constructor path instead of O(heap) - Load-order safe: new subclasses are visible to all instances immediately - Deterministic: set is built in require order, not GC-dependent order Also fix the "recource" typo in the ResourceDependencies comment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01refactor: extract register_keyword helper to eliminate 4x DSL duplicationPaul Buetow
Each of the file/symlink/touch/directory DSL methods repeated the same four-step pattern: nil-path identity return, @conds_met guard, create- configure-register, return object. Add a private register_keyword helper to DSL in dsl.rb and collapse each method to a one-liner. No behaviour changed; all 29 tests continue to pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01refactor: narrow BasicFile interface — apply ISP to Touch and DirectoryPaul Buetow
Touch and Directory inherited content/from from BaseFile but had no use for them. Directory worked around this by repurposing content() as a source-directory path store, which was semantically misleading. Changes: - Move content/from down into BaseFile (only File and Symlink need them) - Move evaluate_absent! up into BasicFile (Touch and Directory need it) - Move UnsupportedOperation up into BasicFile (validate raises it there) - Re-parent Touch and Directory to BasicFile directly - Add Directory#source accessor to replace the content() misuse - Update DSL#directory to call d.source(...) instead of d.content(...) All 29 tests continue to pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01refactor: extract do? into DryRun concern module in resource.rbPaul Buetow
do? (dry-run-aware block execution) was sitting inside ResourceDependencies, which is responsible for dependency tracking — an SRP violation. Move it into its own DryRun module and include that in Resource alongside the existing concerns. No logic changed; all 29 tests continue to pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01refactor: split file.rb into per-class files under lib/dslkeywords/Paul Buetow
file.rb was a ~400-line monolith holding seven unrelated classes/modules. Extract each into its own file so each file has a single responsibility and stays within the 50-line guideline: file_backup.rb — FileBackup mixin symlink.rb — Symlink class + DSL#symlink touch.rb — Touch class + DSL#touch directory.rb — Directory class + DSL#directory file.rb keeps BasicFile, BaseFile, File, and DSL#file. dsl.rb gains explicit require_relative lines for the new files. No logic was changed; all 29 tests continue to pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01fix: correct backup_resursively! typo in evaluate_present_recursively!Paul Buetow
The method is defined as backup_recursively! but was called as backup_resursively! — a NoMethodError at runtime for any configuration using the recursive directory copy directive. Also fix the matching misspelling in the log message string. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01fix: replace shell-interpolation with system() in DNFPackageManagerPaul Buetow
Backtick calls interpolated the package name directly into a shell command string, allowing metacharacters (;, $(), backticks) to execute arbitrary commands. Using system() with separate arguments bypasses the shell entirely, so the package name is passed as a literal argv element to dnf. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01bump version to 0.1.1v0.1.1Paul Buetow
2026-03-01removePaul Buetow
2026-03-01gracefully handle missing toml gem in config.rbPaul Buetow
2026-03-01fix requires syntax in plain_ruby example.rbPaul Buetow
2026-03-01resize DSL screenshot to 70% of original sizePaul Buetow
2026-03-01add DSL syntax screenshot to assets and READMEPaul Buetow
2026-03-01update quickstart examples in README to reflect LoadError fallback and gem usagev0.1.0Paul Buetow
2026-03-01add rcm LoadError fallback to rake and gem examplesPaul Buetow
2026-03-01replace gem example with bundle exec ruby, distinct from rake examplePaul Buetow
2026-03-01fix dry-run crash when parent directory does not exist yet, add rake and rcm ↵Paul Buetow
fallback to examples
2026-03-01fix bin/rcm to fall back to lib/dsl when gem is not installedPaul Buetow
2026-03-01use relative path to bin/rcm in cli example READMEPaul Buetow
2026-03-01clarify location of rcm CLI tool in cli example READMEPaul Buetow
2026-03-01add README.md to each example directory with usage instructionsPaul Buetow
2026-03-01add quickstart examples directory and link from READMEPaul Buetow
2026-03-01add comprehensive README with full DSL reference and setup guidePaul Buetow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01make rcm usable as a gem from any directory, fix bugs and testsPaul Buetow
- Add lib/rcm.rb entry point and bin/rcm CLI executable - Update gemspec: v0.1.0, proper files list, executables, runtime deps - Support standalone arg parsing and --hosts filtering in options - Fix inverted logic and typo in FileBackup#different? (== vs !=, cecksum_b) - Fix unqualified File.directory? resolving to RCM::File in Directory - Fix test_chown assertions running before evaluate! creates files - Add setup to file tests to prevent order-dependent failures Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01addPaul Buetow
2025-11-26update readme with some examplesPaul Buetow
2025-02-28fixPaul Buetow
2025-02-28joPaul Buetow
2025-02-28can copy recursively a directoryPaul Buetow
2025-02-26already donePaul Buetow
2025-02-26only run when resource not yet exists as expectedPaul Buetow
2025-02-26rename dry? to do?Paul Buetow
2025-02-26can change owner of files and dirsPaul Buetow
2025-02-26add mode testPaul Buetow
2025-02-25initial mode supportPaul Buetow
2025-02-25change loggerPaul Buetow
2025-02-25add touch filePaul Buetow
2025-02-25can purge a dirPaul Buetow
2025-02-25add one ore testPaul Buetow
2025-02-22morePaul Buetow